package com.meida.base.provider.listener;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.meida.common.constants.CommonConstants;
import com.meida.common.constants.QueueConstants;
import com.meida.common.security.http.OpenRestTemplate;
import com.meida.common.utils.FlymeUtils;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.RedisUtils;
import com.meida.module.admin.client.entity.BaseAction;
import com.meida.module.admin.client.entity.BaseApi;
import com.meida.module.admin.client.entity.BaseMenu;
import com.meida.module.admin.provider.service.BaseActionService;
import com.meida.module.admin.provider.service.BaseApiService;
import com.meida.module.admin.provider.service.BaseAuthorityService;
import com.meida.module.admin.provider.service.BaseMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Payload;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * mq消息接收者
 *
 * @author zyf
 */
@Configuration
@Slf4j
public class ResourceScanHandler {
    @Autowired
    private BaseApiService baseApiService;
    @Autowired
    private BaseAuthorityService baseAuthorityService;
    @Autowired
    private OpenRestTemplate restTemplate;


    @Autowired
    private BaseActionService baseActionService;

    @Autowired
    private BaseMenuService baseMenuService;

    @Autowired
    private RedisUtils redisUtils;


    /**
     * 接收API资源扫描消息
     */
    @RabbitListener(queues = QueueConstants.QUEUE_SCAN_API_RESOURCE)
    public void ScanApiResourceQueue(@Payload JSONObject resource) {
        try {
            String serviceId = resource.getString("application");
            String notAuthKey = CommonConstants.NOTAUTH_KEY + serviceId;
            JSONArray array = resource.getJSONArray("mapping");
            JSONArray codesArray = resource.getJSONArray("codes");
            Iterator iterator = array.iterator();
            Map<Object, Object> notAuthList = new HashMap<>();
            while (iterator.hasNext()) {
                Map map = (Map) iterator.next();
                try {
                    BaseApi api = JsonUtils.jsonToBean(JsonUtils.beanToJson(map), BaseApi.class);
                    BaseApi baseApi = baseApiService.getApi(api.getApiCode());

                    String actionName = api.getActionName();
                    String menuName = api.getMenuName();
                    if (FlymeUtils.isNotEmpty(menuName)) {
                        BaseMenu baseMenu = baseMenuService.getMenu(menuName);
                        String actionCode = api.getMethodName();
                        Boolean insert = false;
                        BaseAction baseAction = baseActionService.getAction(actionCode);
                        if (FlymeUtils.isEmpty(baseAction)) {
                            baseAction = new BaseAction();
                            baseAction.setIsPersist(CommonConstants.LEVEL_1);
                            baseAction.setStatus(CommonConstants.ENABLED);
                            insert = true;
                        }
                        baseAction.setActionCode(actionCode);
                        baseAction.setActionName(actionName);
                        if (FlymeUtils.isNotEmpty(baseMenu)) {
                            baseAction.setMenuId(baseMenu.getMenuId());
                        }
                        baseAction.setServiceId(api.getServiceId());
                        if (insert) {
                            baseActionService.addAction(baseAction);
                        } else {
                            baseActionService.updateAction(baseAction);
                        }
                    }
                    if (baseApi == null) {
                        api.setIsOpen(1);
                        api.setIsPersist(1);
                        baseApiService.addApi(api);
                        if (api.getIsAuth().equals(0)) {
                            notAuthList.put(api.getApiCode(), api.getPath());
                        }
                    } else {
                        api.setApiId(baseApi.getApiId());
                        api.setIsAuth(null);
                        if (baseApi.getIsAuth().equals(0)) {
                            notAuthList.put(baseApi.getApiCode(), baseApi.getPath());
                        }
                        baseApiService.updateApi(api);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("添加资源error:", e.getMessage());
                }

            }
            //免登录鉴权接口
            if (FlymeUtils.isNotEmpty(notAuthList)) {
                redisUtils.setMap(notAuthKey, notAuthList);
            }
            if (FlymeUtils.isNotEmpty(codesArray)) {
                List<String> codes = JSONObject.parseArray(codesArray.toJSONString(), String.class);
                // 清理无效权限数据
                baseAuthorityService.clearInvalidApi(serviceId, codes);
                restTemplate.refreshGateway();
            }

        } catch (
                Exception e) {
            log.error("error:", e);
        }
    }
}
